var
    swiper = require("swiper"),
    angular_swiper = require("angular-swiper");
angular
    .module("utilsModule", [
        "ksSwiper"
    ])
    .service("httpServerErrorMsg", [
        function() {

            var
                statusStack = [],
                hashStatus = {};

            statusStack.push({
                status: 404,
                msg: "地址错误！"
            }, {
                status: 403,
                msg: "访问权限不足",
                serverFirst: true
            });

            statusStack.forEach(function(statusInfo) {
                hashStatus[statusInfo.status] = statusInfo;
            });

            this.getErrorMsg = getErrorMsg;

            /**
             * 获取错误信息
             * @param { Number } statusCode
             * @param { String } [serverMsg]
             * @returns {*|string}
             */
            function getErrorMsg(statusCode, serverMsg) {

                var
                    retInfo = hashStatus[statusCode];

                if (!retInfo) {
                    return serverMsg ? serverMsg : "";
                }

                return (retInfo.serverFirst ? serverMsg || retInfo.msg : retInfo.msg);
            }

        }
    ])
    .service("sanHttp", [
        "$q",
        "httpServerErrorMsg",
        "$window",
        "$http",
        function($q, httpServerErrorMsg, $window, $http) {
            var
                http = this;

            /**
             *
             * @param { String } type "Http Method"
             * @param { Object } onf
             * @param { Object } onf.data 数据
             * @param { Function } [onf.beforeSend] 在发送请求之前调用
             * @param { Function } [onf.success] 成功回调
             * @param { Function } [onf.error] 失败回调
             * @param { Boolean } [onf.isSilent] 是否开启静默
             * @param { String } [onf.specUrlPrefix] 强制启用专有接口url 前缀
             * @param { Number } [onf.timeout] 超时毫秒时间
             * @param { Boolean } [onf.isTron] 是否采用新移动校园数据传递
             * @param { Boolean } [onf.isSecure] 是否采用加密传输
             */
            http.get = function(type, onf) {
                return http.http($window.angular.extend({ method: "get", type: type }, onf));
            };

            /**
             *
             * @param type
             * @param onf
             * @param { Object } onf 同 http.get
             */
            http.post = function(type, onf) {
                return http.http($window.angular.extend({ method: "post", type: type }, onf));
            };

            /**
             *
             * @param { Object } onf
             * @param { String } onf.method "Http Method"
             * @param { String } onf.type 数据接口名称常量
             * @param { Object } [onf.data] 数据
             * @param { Function } [onf.beforeSend] 在发送请求之前调用
             * @param { Function } [onf.success] 成功回调
             * @param { Function } [onf.error] 失败回调
             * @param { Boolean } [onf.isSilent] 是否开启静默
             * @param { String } [onf.specUrlPrefix] 强制启用专有接口url 前缀
             * @param { String } [onf.specUrl] 启用专有接口url 后缀
             * @param { Number } [onf.timeout] 超时毫秒时间
             * @param { Boolean } [onf.isTron] 是否采用新移动校园数据传递
             * @param { Boolean } [onf.isSecure] 是否采用加密传输
             */
            http.http = function(onf) {
                return http.create().http(onf);
            };

            http.create = function() {
                return Object.create(http.prototype);
            };

            http.prototype = {
                /**
                 * 参数说明同 http.http
                 * @param onf
                 * @returns {http}
                 */
                http: function(onf) {

                    var
                        _deferExternal = $q.defer(),
                        _deferHttp = $q.defer(),
                        isLoading,

                        promiseTime,
                        iHttp = this;

                    onf = onf || {};
                    iHttp.rawConfig = onf;

                    // 超时处理设定
                    promiseTime = iHttp._processTimeout(onf);

                    isLoading = true;

                    iHttp
                        ._processRequest(onf)
                        .then(function(requestInfo) {
                            return $http(requestInfo);
                        })
                        .then(_deferHttp.resolve, _deferHttp.reject, _deferHttp.notify);

                    _deferHttp.promise.finally(_onTimeComplete);
                    _deferHttp.promise.then(_resolve, _reject, _notify);

                    /**
                     * 即时处理 请求完成
                     * @private
                     */
                    function _onTimeComplete() {
                        isLoading = false;

                        // 清除超时处理定时器
                        promiseTime && clearTimeout(promiseTime);
                    }

                    /**
                     * 成功请求返回
                     * @returns {*}
                     * @private
                     */
                    function _resolve(res) {

                        iHttp.
                        _processResponse(res)
                            .then(function(data) {

                                _deferExternal.resolve(data);
                                "function" === typeof onf.success && onf.success(data);

                            }, function(res) {

                                "function" === typeof onf.error && onf.error(res);
                                _deferExternal.reject(res);

                                console.log([
                                    "--- 错误返回 ---",
                                    " -url：", res.config.url,
                                    " -参数：", (res.config.data || res.config.params),
                                    "--- End ---"
                                ].join("\n"));

                                if (!onf.isSilent) {
                                    console.log(res.data.msg || "数据接口暂不可用, 请稍后再试!");
                                }

                            });
                    }

                    /**
                     * 失败请求返回
                     * @param res
                     * @returns {*}
                     * @private
                     */
                    function _reject(res) {

                        var
                            _errMsg,
                            _resData;

                        _resData = res.data || {};
                        res.config = res.config || {};

                        _errMsg = httpServerErrorMsg.getErrorMsg(Number(res.status), _resData.msg) || res.message;

                        if (!onf.isSilent && _errMsg) {
                            console.log(_errMsg);
                        }

                        "function" === typeof onf.error && onf.error(res);
                        _deferExternal.reject(res);

                        console.log(_errMsg + "\n --url：" + res.config.url + "\n --参数：", (res.config.data || res.config.params));

                        return res;

                    }

                    /**
                     * Progress 处理
                     * @param res
                     * @private
                     */
                    function _notify(res) {
                        _deferExternal.notify(res);
                    }

                    iHttp._defer = _deferHttp;

                    // 注入 promise 方法
                    $window.angular.extend(iHttp, _deferExternal.promise);

                    ["catch", "finally", "then"].forEach(function(api) {
                        iHttp[api] = _deferExternal.promise[api].bind(_deferExternal.promise);
                    });

                    return iHttp;

                },
                _processTimeout: (onf) => {
                    var
                        timeout = onf.timeout,
                        _promiseTime,
                        _this = this;

                    timeout = "number" === typeof onf.timeout && timeout === timeout ? timeout : null;

                    // 超时处理
                    if (timeout) {
                        _promiseTime = setTimeout(function() {
                            _this.dump();
                        }, timeout);
                    }

                    return _promiseTime;

                },
                _processRequest: (rawConfig) => {

                    var
                        _deferProcess = $q.defer(),
                        reqConf,
                        rawReqData,

                        _this = this;


                    // 字符串化
                    rawReqData = rawConfig.data || {};
                    rawReqData = rawReqData && "object" === typeof rawReqData && "POST" === rawConfig.method.toUpperCase() ?
                        JSON.stringify(rawReqData) :
                        rawReqData;

                    reqConf = {
                        url: rawConfig.url,
                        method: rawConfig.method.toUpperCase() || "POST",
                        headers: {
                            "Content-Type": "application/json;charset=UTF-8",
                            // "token": rawConfig.token,
                             // sid: SAN_GLOBAL.sid || null,
                            "Accept-Language": "zh-CN"
                        },
                        data: rawReqData,
                        params: rawReqData,
                    };

                    // 处理 POST/GET 传参
                    delete reqConf["POST" === reqConf.method ? "params" : "data"];

                    _deferProcess.resolve(reqConf);

                    return _deferProcess.promise;
                },
                _processResponse: (function() {

                    return function(res) {

                        var iHttp = this;

                        return $q(function(resolve, reject) {

                            var
                                _resRawData = res.data;
                            _assertResponse(_resRawData, res, resolve, reject);
                        });

                    };

                    /**
                     * 断言 返回业务数据 resolve or reject
                     * @param { Object } data
                     * @param { Object } res response 返回数据
                     * @param { Function } resolve
                     * @param { Function } reject
                     */
                    function _assertResponse(data, res, resolve, reject) {

                        if (1 === Number(data.msgState)) {
                            resolve(data);

                        } else {
                            res.data = data || res.data;
                            reject(res);
                        }
                    }

                })()
            }
        }
    ]);